<?php
/**
 * 囤福家园
 *
 * @copyright © 2022 by 技术先锋 All rights reserved。
 * @Created   by PhpStorm.
 * @author    StarsPhp
 * @date      2023/2/14
 * @time      15:07
 */
declare (strict_types=1);

namespace app\command\workerman;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use Workerman\Worker;

class workermanRun extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('WorkermanRun')
            ->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload|status|connections", 'start')
            ->addOption('mode', 'm', Option::VALUE_OPTIONAL, 'Run the workerman server in daemon mode.')
            ->setDescription('GatewayWorker Server for ThinkPHP_starsphp the workerman command');
    }
    
    protected function execute(Input $input, Output $output)
    {
        // 指令输出
        $output->writeln('GatewayWorker Server for ThinkPHP_starsphp the workerman command: im start');
        
        $action = $input->getArgument('action');
        $mode = $input->getOption('mode');
        
        
        // 重新构造命令行参数,以便兼容workerman的命令
        global $argv;
        
        $argv = [];
        
        array_unshift($argv, 'think', $action);
        if ($mode == 'd') {
            $argv[] = '-d';
        } else if ($mode == 'g') {
            $argv[] = '-g';
        }
        
        
        if (strpos(strtolower(PHP_OS), 'win') === 0) {
            exit("start.php not support windows, please use start_for_win.bat\n");
        }
        
        // 检查扩展
        if (!extension_loaded('pcntl')) {
            exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
        }
        
        if (!extension_loaded('posix')) {
            exit("Please install posix extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
        }
        
        // 标记是全局启动
        define("GLOBAL_START", 1);
        
        // 运行基础目录
        define("RUNTIME_BASE_PATH", __DIR__ . '/../../../utils/workerman');
        
        
        // define("CONFIG", require_once __DIR__ . '/../../config/workerman.php');
        
        if (!is_dir(RUNTIME_BASE_PATH)) {
            mkdir(RUNTIME_BASE_PATH, 0777, true);
        }
        
        // // 加载所有 functions/*.php 的函数，以便启动所有服务时使用
        foreach(glob(RUNTIME_BASE_PATH.'/../functions/*.php') as $start_file)
        {
            require_once $start_file;
        }
        
        
        // 此属性为全局静态属性，表示是否以daemon(守护进程)方式运行。
        //如果启动命令使用了 -d参数，则该属性会自动设置为true。也可以代码中手动设置。
        // Worker::$daemonize = true;
        
        // 此属性为全局静态属性，如果以守护进程方式(-d启动)运行，则所有向终端的输出(echo var_dump等)都会被重定向到stdoutFile指定的文件中。
        // 如果不设置，并且是以守护进程方式运行，则所有终端输出全部重定向到/dev/null (也就是默认丢弃所有输出)
        // 注意：/dev/null 是linux下一个特殊文件，它实际上是一个黑洞，所有数据写入到这个文件都会被丢弃。
        //如果不想丢弃输出，可以将Worker::$stdoutFile设置成一个正常文件路径。
        // 注意：此属性必须在Worker::runAll();运行前设置才有效。windows系统不支持此特性。
        // 所有的打印输出全部保存在/tmp/stdout.log文件中
        Worker::$stdoutFile = RUNTIME_BASE_PATH .'/stdout.log';
        
        // 如果无特殊需要，建议不要设置此属性
        // 此属性为全局静态属性，用来设置WorkerMan进程的pid文件路径。
        // 此项设置在监控中比较有用，例如将WorkerMan的pid文件放入固定的目录中，可以方便一些监控软件读取pid文件，从而监控WorkerMan进程状态。
        // 如果不设置，WorkerMan默认会在与Workerman目录平行的位置（注意workerman3.2.3之前版本默认在sys_get_temp_dir()下）自动生成一个pid文件，
        //并且为了避免启动多个WorkerMan实例导致pid冲突，WorkerMan生成pid文件包含了当前WorkerMan的路径
        // 注意：此属性必须在Worker::runAll();运行前设置才有效。windows系统不支持此特性。
        Worker::$pidFile = RUNTIME_BASE_PATH . '.pid';
        
        // 用来指定workerman日志文件位置。
        // 此文件记录了workerman自身相关的日志，包括启动、停止等。
        // 如果没有设置，文件名默认为workerman.log，文件位置位于Workerman的上一级目录中。
        // 注意：
        // 这个日志文件中仅仅记录workerman自身相关启动停止等日志，不包含任何业务日志。
        // 业务日志类可以利用file_put_contents 或者 error_log 等函数自行实现。
        Worker::$logFile = RUNTIME_BASE_PATH . '/run.log';
        
        // 加载所有 workerman/*/start.php，以便启动所有服务
        foreach(glob(RUNTIME_BASE_PATH.'/start*.php') as $start_file)
        {
            require_once $start_file;
        }
        
        // 运行所有服务
        Worker::runAll();
    }
}
